#pragma once
#define ENABLE_ENCRYPT
class AES  
{
public:
	AES(unsigned char* key);
	virtual ~AES();
#ifdef ENABLE_ENCRYPT
	unsigned char* Encrypt(unsigned char* input);
	void* Encrypt(void* input, int length=0);
#endif

	void* Decrypt(void* input, int length);
	unsigned char* Decrypt(unsigned char* input);

private:
	static const unsigned char Sbox[256];
	static const unsigned char InvSbox[256];
	unsigned char w[11][4][4];

	void KeyExpansion(unsigned char* key, unsigned char w[][4][4]);
	unsigned char FFmul(unsigned char a, unsigned char b);

	void SubBytes(unsigned char state[][4]);
	void ShiftRows(unsigned char state[][4]);
	void MixColumns(unsigned char state[][4]);
	void AddRoundKey(unsigned char state[][4], unsigned char k[][4]);

	void InvSubBytes(unsigned char state[][4]);
	void InvShiftRows(unsigned char state[][4]);
	void InvMixColumns(unsigned char state[][4]);
};

